// Write C++ code here.
//
// Do not forget to dynamically load the C++ library into your application.
//
// For instance,
//
// In MainActivity.java:
//    static {
//       System.loadLibrary("app");
//    }
//
// Or, in MainActivity.kt:
//    companion object {
//      init {
//         System.loadLibrary("app")
//      }
//    }

#include "LogHelper.h"
#include "jni.h"
#include "GLES3/gl3.h"

#define NATIVE_RENDER_CLASS_NAME "com/hy/app/NativeColorRender"

#ifdef __cplusplus
extern "C" {
#endif

void onSurfaceCreated(JNIEnv *env, jobject instance, jint color) {
    //分离RGBA的百分比
    GLfloat redF = ((color >> 16) & 0xFF) * 1.0f / 255;
    GLfloat greenF = ((color >> 8) & 0xFF) * 1.0f / 255;
    GLfloat blueF = (color & 0xFF) * 1.0f / 255;
    GLfloat alphaF = ((color >> 24) & 0xFF) * 1.0f / 255;
    glClearColor(redF, greenF, blueF, alphaF);
}

void onSurfaceChanged(JNIEnv *env, jobject instance, jint width, jint height) {
    glViewport(0, 0, width, height);
}

void onDrawFrame(JNIEnv *env, jobject instance) {
    glClear(GL_COLOR_BUFFER_BIT);
}

static JNINativeMethod g_RenderMethods[] = {
        {"onSurfaceCreated", "(I)V", (void *) onSurfaceCreated},
        {"onSurfaceChanged", "(II)V", (void *) onSurfaceChanged},
        {"onDrawFrame", "()V", (void *) onDrawFrame},
};

static jint
RegisterNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int methodNum) {
    LOGI("RegisterNativeMethods");
    jclass clazz = env->FindClass(className);
    if (clazz == NULL) {
        LOGI("RegisterNativeMethods fail. clazz == NULL");
        return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, methods, methodNum) < 0) {
        LOGI("RegisterNativeMethods fail");
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

void UnregisterNativeMethods(JNIEnv *env, const char *className) {
    LOGI("UnregisterNativeMethods");
    jclass clazz = env->FindClass(className);
    if (clazz == NULL) {
        LOGI("UnregisterNativeMethods fail. clazz == NULL");
        return;
    }
    env->UnregisterNatives(clazz);
}

// call this func when loading lib
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *p) {
    LOGI("===== JNI_OnLoad =====");
    jint jniRet = JNI_ERR;
    JNIEnv *env = NULL;
    if (jvm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return jniRet;
    }

    jint regRet = RegisterNativeMethods(env, NATIVE_RENDER_CLASS_NAME, g_RenderMethods,
                                        sizeof(g_RenderMethods) /
                                        sizeof(g_RenderMethods[0]));
    if (regRet != JNI_TRUE) {
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *p) {
    JNIEnv *env = NULL;
    if (jvm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return;
    }

    UnregisterNativeMethods(env, NATIVE_RENDER_CLASS_NAME);
}

#ifdef __cplusplus
}
#endif